﻿using Mapster;
using Microsoft.AspNetCore.Mvc;
using RuoVea.DynamicWebApi;
using RuoVea.ExDto;
using RuoVea.ExEnum;
using RuoVea.ExSugar;
using RuoVea.ExSugar.Entity;
using RuoVea.ExUtil;
using RuoVea.OmiApi.Article.Entitys;
using RuoVea.OmiApi.Article.Service.Dto;
using System.ComponentModel;
using exDtoi18n = RuoVea.ExDto.Language.i18n;

namespace RuoVea.OmiApi.Article.Service;

/// <summary>
/// 标签管理 🔷
/// </summary>
[ApiExplorerSettings(GroupName = "art")]
public class TagService : IApplicationService
{
    private readonly SugarRepository<ArtTag> _thisRepository;
    private readonly SugarRepository<ArtArticleTag> _articleTagRepository;

    /// <summary>
    /// 参数配置表
    /// </summary>
    /// <param name="thisRepository"></param>
    /// <param name="articleTagRepository"></param>
    public TagService(SugarRepository<ArtTag> thisRepository, SugarRepository<ArtArticleTag> articleTagRepository)
    {
        _thisRepository = thisRepository;
        _articleTagRepository = articleTagRepository;
    }

    /// <summary>
    /// 查询所有/分页🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<PageResult<TagDto>> GetPagesAsync([FromQuery] TagParam data)
    {
        var code = !string.IsNullOrEmpty(data.Code?.Trim());
        var name = !string.IsNullOrEmpty(data.Name?.Trim());

        var query = await _thisRepository.AsQueryable()
            .Where(u => u.IsDelete == IsDelete.N)
            .WhereIF(code, u => u.Code.Contains(data.Code))
            .WhereIF(name, u => u.Name.Contains(data.Name))
            .WhereIF(data.UserId > 0, u => u.Creator == data.UserId)
            .OrderBy(u => u.Sort)
            .ToPageAsync<ArtTag, TagDto>(data.PageNo, data.PageSize);
        return query;
    }

    /// <summary>
    /// 获取列表🔹
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取列表")]
    public async Task<List<ArtTag>> GetAllList()
    {
        var query = _thisRepository.AsQueryable().OrderBy(u => u.Sort).OrderByDescending(u => u.CreateTime);
        return await query.ToListAsync();
    }

    /// <summary>
    /// 获取列表🔹
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取列表")]
    public List<ArtIdCodeName> GetList(TagParam data)
    {
        var code = !string.IsNullOrEmpty(data.Code?.Trim());
        var name = !string.IsNullOrEmpty(data.Name?.Trim());

        var query = _thisRepository.AsQueryable()
            .WhereIF(code, u => u.Code.Contains(data.Code))
            .WhereIF(name, u => u.Name.Contains(data.Name))
            .OrderByDescending(u => u.CreateTime)
            .OrderBy(u => u.Sort)
            .Select(u => new ArtIdCodeName { 
                Id = u.Id, 
                Code = u.Code, 
                Name = u.Name 
            });
        return query.ToPageList(data.PageNo, data.PageSize);
    }

    /// <summary>
    /// 获取列表🔹
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取列表")]
    public async Task<List<ArtTag>> GetListByUserId(long userId)
    {
        var query = _thisRepository.AsQueryable()
            .Where(u => u.Creator == userId)
            .OrderBy(u => u.Sort)
            .OrderByDescending(u => u.CreateTime);
        return await query.ToListAsync();
    }

    /// <summary>
    /// 添加🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<bool> AddDataAsync([FromBody] TagDto data)
    {
        var isExist = await _thisRepository.IsAnyAsync(u => (u.Name == data.Name || u.Code == data.Code) && u.IsDelete == 0);

        if (isExist) throw new ArgumentException(ErrorEnum.D9000.GetDescription(exDtoi18n.ResourceManager));

        var dictType = data.Adapt<ArtTag>();

        return await _thisRepository.InsertAsync(dictType);
    }

    /// <summary>
    /// 修改🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task UpdateDataAsync([FromBody] TagDto data)
    {
        var isExist = await _thisRepository.IsAnyAsync(u => u.Id == data.Id);
        if (!isExist) throw new ArgumentException(ErrorEnum.D1002.GetDescription(exDtoi18n.ResourceManager));

        var dictType = data.Adapt<ArtTag>();
        dictType.Check();

        // 排除自己并且判断与其他是否相同
        isExist = await _thisRepository.IsAnyAsync(u => (u.Name == data.Name || u.Code == data.Code) && u.Id != data.Id && u.IsDelete == 0);
        if (isExist) throw new ArgumentException(ErrorEnum.D9000.GetDescription(exDtoi18n.ResourceManager));

        await _thisRepository.UpdateAsync(dictType);
    }

    /// <summary>
    /// 删除🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task DeleteDataAsync([FromBody] EntityBaseId data)
    {
        data.Check();

        var dictType = await _thisRepository.GetFirstAsync(u => u.Id == data.Id);
        if (dictType == null) throw new ArgumentException(ErrorEnum.D1002.GetDescription(exDtoi18n.ResourceManager));

        // 有文章不让删除
        bool isAny = await _articleTagRepository.IsAnyAsync(x => x.TagId == dictType.Id);
        if (isAny) throw new ArgumentException(ErrorEnum.D1007.GetDescription(exDtoi18n.ResourceManager));

        if (dictType.IsDelete == IsDelete.Y)
            await _thisRepository.DeleteByIdAsync(data.Id);
        else
        {
            dictType.IsDelete = IsDelete.Y;

            await _thisRepository.UpdateAsync(dictType);
        }
    }
}